package org.hilo.boot.scaffold;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.jretty.log.LogFactory;
import org.jretty.log.Logger;
import org.jretty.util.Const;
import org.jretty.util.HttpClientStaticBuilder;
import org.jretty.util.NestedRuntimeException;

import org.hilo.boot.core.UT;


/**
 * 脚手架生成器通用父类
 * 
 * @author zollty
 * @since 2020-5-12
 */
public abstract class AbstractGenerator {
    protected Logger logger = LogFactory.getLogger(getClass());
    /**
     * 自定义资源路径，默认从maven拉取
     */
    protected String source;
    /**
     * 用途（场景化类型）： admin, dubbo 等
     */
    protected String useType;
    protected String groupId; 
    protected String artifactId;
    protected String basePackage;
    
    protected String targetBasePath;
    
    protected boolean separateBizApp;
    
    protected boolean demoMode;
    
    protected String sourceFileUrl;

    boolean getSourceFile(String toPath) {
        CloseableHttpClient httpclient = HttpClientStaticBuilder.buildDefault();
        HttpGet request = new HttpGet(sourceFileUrl);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();
            entity.writeTo(new FileOutputStream(new File(toPath)));
            // do something useful with the response body
            // and ensure it is fully consumed
            EntityUtils.consume(entity);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            UT.IO.close(response);
            UT.IO.close(httpclient);
        }
    }
    
    static void deleteIDEFiles(String basePath) {
        deleteAll(basePath + ".settings");
        deleteAll(basePath + "target");
        deleteAll(basePath + ".classpath");
        deleteAll(basePath + ".project");
    }
    
    static String getFileContent(String fileFullPath) {
        try {
            return UT.File.getTextContent(new FileInputStream(fileFullPath), null);
        } catch (FileNotFoundException e) {
            throw new NestedRuntimeException(e);
        }
    }
    
    static void deleteAll(String path) {
        UT.File.deleteAll(new File(path));
    }
    
    static void renameTo(String from, String to) {
        new File(to).delete();
        new File(from).renameTo(new File(to));
    }
    
    static class Rep {
        private String fromPath;
        private String toPath;
        private String content;

        static Rep build(String fromPath, String toPath) {
            Rep rep = new Rep();
            rep.fromPath = fromPath;
            rep.toPath = toPath;
            rep.content = getFileContent(fromPath);
            return rep;
        }

        Rep replace(String oldPattern, String newPattern) {
            content = UT.Str.replace(content, oldPattern, newPattern);
            return this;
        }
        
        Rep replaceBetween(String idx1, String idx2, String newStr) {
            content = SgTools.replaceBetween(content, idx1, idx2, newStr);
            return this;
        }
        
        Rep deleteStartLine(String startContent) {
            content = SgTools.stripMiddleOfIndex(content, startContent, Const.CRLF);
            return this;
        }
        
        Rep deleteLine(String deleteContent) {
            content = UT.Str.replace(content, deleteContent + Const.CRLF, "");
            return this;
        }
        
        Rep append(String appendContent) {
            content = content + Const.CRLF + appendContent;
            return this;
        }

        void apply() {
            apply(true);
        }
        
        void apply(boolean del) {
            if (toPath == null) {
                toPath = fromPath;
                SgTools.replaceFile(toPath, content);
            } else {
                SgTools.replaceFile(toPath, content);
                if(del) {
                    new File(fromPath).delete();
                }
            }
        }
    }
    
    /**
     * 自定义本地资源路径
     */
    public void setSource(String source) {
        this.source = source;
    }

    /**
     * @param sourceFileUrl the sourceFileUrl to set
     */
    public void setSourceFileUrl(String sourceFileUrl) {
        this.sourceFileUrl = sourceFileUrl;
    }
    
//
//    /**
//     * @param useType the useType to set
//     */
//    public void setUseType(String useType) {
//        this.useType = useType;
//    }
//
//    /**
//     * @param groupId the groupId to set
//     */
//    public void setGroupId(String groupId) {
//        this.groupId = groupId;
//    }
//
//    /**
//     * @param artifactId the artifactId to set
//     */
//    public void setArtifactId(String artifactId) {
//        this.artifactId = artifactId;
//    }
//
//
//    /**
//     * @param basePackage the basePackage to set
//     */
//    public void setBasePackage(String basePackage) {
//        this.basePackage = basePackage;
//    }
//
//    /**
//     * @param copyFileToPath the copyFileToPath to set
//     */
//    public void setCopyFileToPath(String copyFileToPath) {
//        if (copyFileToPath != null && new File(copyFileToPath).exists()) {
//            throw new IllegalStateException("copyFileToPath已存在，默认不覆盖，请指定一个新路径");
//        }
//        this.copyFileToPath = copyFileToPath;
//    }
//
//    /**
//     * 业务和配置分离————分成业务子工程（hilodemo-biz）和APP入口配置子工程(hilodemo)
//     * @param separateBizApp true代表分开，false代表揉在一起
//     */
//    public void setSeparateBizApp(boolean separateBizApp) {
//        this.separateBizApp = separateBizApp;
//    }
//
//    /**
//     * @return the sourceFileUrl
//     */
//    public String getSourceFileUrl() {
//        return sourceFileUrl;
//    }

}

